// AbstractView.m

#import "AbstractView.h"
#import "Controller.h"
#import <stdio.h>

@implementation AbstractView

- initFrame:(const NXRect *)frameRect
{
	[super initFrame:frameRect];
	xMin = -100;
	xMax = 100;
	yMin = -100;
	yMax = 100;
	[self display];
	return self;
}

- newLimits:sender
{
	xMin = [xMinField floatValue];
	xMax = [xMaxField floatValue];
	yMin = [yMinField floatValue];
	yMax = [yMaxField floatValue];
	[self display];
	return self;
}
	
#define X(x) ((x - xMin) * sx)
#define Y(y) ((y - yMin) * sy)

- drawSelf:(const NXRect *)rects :(int)rectCount
{
	float sx = bounds.size.width / (xMax - xMin);
	float sy = bounds.size.height / (yMax - yMin);
	id font = [Font newFont:"Helvetica" size:12.0 matrix:NX_IDENTITYMATRIX];
		
	// erase view
	NXEraseRect(&rects[0]);
	
	// draw axes
	PSsetgray(NX_BLACK);
	PSmoveto(X(xMin), Y(0.0));
	PSlineto(X(xMax), Y(0.0));
	PSstroke();
	PSmoveto(X(0.0), Y(yMin));
	PSlineto(X(0.0), Y(yMax));
	PSstroke();
	
	// set font for later
	[font set];
	
	return self;
}

- (BOOL)acceptsFirstResponder
{
	return YES;
}

- copy:sender
{
	NXStream *stream;
	NXAtom typelist[1] = { NXPostScriptPboardType };
	int length, maxLength;
	char *data;
	id pboard = [Pasteboard new];	

	// put EPS on the pasteboard
NX_DURING
	[pboard declareTypes:typelist num:1 owner:self];
	stream = NXOpenMemory(NULL, 0, NX_READWRITE);
	[self copyPSCodeInside:&bounds to:stream];
	NXGetMemoryBuffer(stream, &data, &length, &maxLength);
	[pboard writeType:NXPostScriptPboardType data:data length:length];
	NXCloseMemory(stream, NX_FREEBUFFER);
NX_HANDLER
	NXRunAlertPanel("Error", "Can't copy EPS to the pasteboard.", NULL, NULL, NULL);
NX_ENDHANDLER
	return self;
}

#define ZOOM_FACTOR 1.2

- zoomIn:sender
{
	xMin /= ZOOM_FACTOR;
	yMin /= ZOOM_FACTOR;
	xMax /= ZOOM_FACTOR;
	yMax /= ZOOM_FACTOR;
	[self displayLimits];
	[self display];
	return self;
}

- zoomOut:sender
{
	xMin *= ZOOM_FACTOR;
	yMin *= ZOOM_FACTOR;
	xMax *= ZOOM_FACTOR;
	yMax *= ZOOM_FACTOR;
	[self displayLimits];
	[self display];
	return self;
}

- (void)displayLimits
{
	[xMinField setFloatValue: xMin];
	[xMaxField setFloatValue: xMax];
	[yMinField setFloatValue: yMin];
	[yMaxField setFloatValue: yMax];
}

- awakeFromNib
{
	[self displayLimits];
	return self;
}

@end
